package com.mx.project.controller;

import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.mx.project.common.resp.ApiResult;
import com.mx.project.common.util.JWTService;
import com.mx.project.common.util.VerifyCodeUtils;
import com.mx.project.constants.Constants;
import com.mx.project.pojo.LoginUser;
import com.mx.project.pojo.User;
import com.mx.project.services.UserService;
import io.swagger.annotations.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Log4j2
@Api(tags = "主要用于登录注册")
@RestController
@RequestMapping("mx")
public class LoginController {

    @Autowired
    private VerifyCodeUtils verifyCodeUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JWTService jwtService;

    @ApiOperation("用户登录接口")
    @ApiResponses({
            @ApiResponse(code = 200,message = "登录成功,使用user即可获取对象值"),
            @ApiResponse(code = 400,message = "非法登录"),
            @ApiResponse(code = 420,message = "用户未注册"),
            @ApiResponse(code = 421,message = "用户密码错误"),
    })
    @PostMapping("login")
    public ApiResult login(@RequestBody @Validated LoginUser loginUser, HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        String vct = request.getSession().getId();
        String vc = (String)redisTemplate.opsForValue().get(vct);
        if(!loginUser.getVc().toUpperCase().equals(vc)){
            return new ApiResult(Constants.VC_ERROR, "验证码错误!");
        }
        if (userService.findUserByUsername(loginUser.getUsername()) == null) {
            return new ApiResult(Constants.USER_NOT_REGISTER, "用户未注册!");
        }
        User res = userService.checkPassword(loginUser.getUsername(),loginUser.getPassword());
        if(res == null){
            return new ApiResult(Constants.USER_PASSWORD_ERROR, "用户密码错误!");
        }
        Map<String,String> userInfo = jwtService.createUserUid(res);
        String token = jwtService.createToken(userInfo, Constants.TOKEN_EXPIRE_TIME);
        //todo token
        ServletContext servletContext = request.getServletContext();
        servletContext.setAttribute(token,token);
        apiResult.setData(token);
        return apiResult;
    }


    @ApiOperation("注册接口")
    @ApiResponses({
            @ApiResponse(code = 200,message = "注册成功"),
            @ApiResponse(code = 410,message = "验证码已失效"),
            @ApiResponse(code = 411,message = "验证码不匹配"),
            @ApiResponse(code = 400,message = "用户已存在 || 数据导入失败"),
    })
    @PostMapping("register")
    public ApiResult<String> register(@RequestBody User user,HttpServletRequest request){
        ApiResult<String> apiResult = new ApiResult();
        String token = request.getSession().getId();
        String vc = (String) redisTemplate.opsForValue().get(token);
        if(StringUtils.isEmpty(vc)){
            return new ApiResult<>(Constants.VC_INVALID,"验证码已失效!");
        }
        if (!vc.equals(user.getVc().toUpperCase())) {
            return new ApiResult<>(Constants.VC_ERROR,"验证码不匹配!");
        }
        //根据用户手机号 , 用户邮箱 , 用户昵称 ,查找数据库中是否已存在该用户.
        if(userService.findUserByUserInfo(user) != null){
            return new ApiResult<>(Constants.RESP_STATUS_BADREQUEST,"用户已存在!");
        }
        //拼接头像字符串
        user.setCreateTime(new Date());
        int id = userService.addUser(user);
        if(id != 1){
            return new ApiResult<>(Constants.RESP_STATUS_BADREQUEST,"数据导入失败!");
        }
        apiResult.setData("uid="+user.getUid());
        return apiResult;
    }

    @ApiOperation("获取图片验证码")
    @GetMapping("imageVerificationCode")
    public ApiResult<Map> generateVerificationCode(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        synchronized (this){
            Map<String, Object> map = new HashMap<>();
//            // 生成文字验证码
//            String text = producer.createText();
//            // 生成图片验证码
//            ByteArrayOutputStream outputStream = null;
//            BufferedImage image = producer.createImage(text);
//            outputStream = new ByteArrayOutputStream();
//            ImageIO.write(image, "jpg", outputStream);
//            //
//            BASE64Encoder encoder = new BASE64Encoder();
//            String imageStr = encoder.encode(outputStream.toByteArray());
//            map.put("img", imageStr);
            String verifyCode = verifyCodeUtils.generateVerifyCode(4);
            ByteArrayOutputStream outputStream  = new ByteArrayOutputStream();
            try {
                verifyCodeUtils.outputImage(100,40,outputStream,verifyCode);
            } catch (IOException e) {
                log.error(e.getCause());
            }
            BASE64Encoder encoder = new BASE64Encoder();
            String imageStr = encoder.encode(outputStream.toByteArray());
            map.put("img",imageStr);
            //根据sessionId来判断不同用户的请求
            String token = request.getSession().getId();
            map.put("verifyCode",verifyCode);
            redisTemplate.opsForValue().set(token, verifyCode, Constants.VERIFY_CODE_EXPIRE_TIME, TimeUnit.MINUTES);
            apiResult.setData(map);
        }
        return apiResult;
    }


    @ApiOperation("验证username是否已经注册")
    @ApiResponses({
            @ApiResponse(code = 200,message = "请求成功"),
            @ApiResponse(code = 400,message = "username已存在"),
    })
    @PostMapping("/verifyUsername")
    public ApiResult verifyUsername(@RequestParam("username") String username){
        ApiResult result = new ApiResult();
        User user = userService.findUserByUsername(username);
        if(user!=null){
            return new ApiResult(Constants.RESP_STATUS_BADREQUEST,"username已存在");
        }
        return result;
    }

    @ApiOperation("验证Email是否已经注册")
    @ApiResponses({
            @ApiResponse(code = 200,message = "请求成功"),
            @ApiResponse(code = 400,message = "此email已存在"),
    })
    @PostMapping("/verifyEmail")
    public ApiResult verifyEmail(@RequestParam("email") String email){
        ApiResult result = new ApiResult();
        User user = userService.findUserByEmail(email);
        if(user!=null){
            return new ApiResult(Constants.RESP_STATUS_BADREQUEST,"此email已存在");
        }
        return result;
    }

    @ApiOperation("验证phone是否已经注册")
    @ApiResponses({
            @ApiResponse(code = 200,message = "请求成功"),
            @ApiResponse(code = 400,message = "此phone已存在"),
    })
    @PostMapping("/verifyPhone")
    public ApiResult verifyPhone(@RequestParam("phone") String phone){
        ApiResult result = new ApiResult();
        User user = userService.findUserByPhone(phone);
        if(user!=null){
            return new ApiResult(Constants.RESP_STATUS_BADREQUEST,"此phone已存在");
        }
        return result;
    }

    @ApiOperation("登出接口.由前端实现,清除Token即可")
    @GetMapping("/logout")
    public ApiResult logout(HttpServletRequest request){
        String token = request.getHeader("token");
        ServletContext servletContext = request.getServletContext();
        servletContext.removeAttribute(token);
        return new ApiResult();
    }

}
